﻿﻿package com.ui.containers
{
	import com.ui.controls.Button;
	import com.ui.controls.ScrollBar;
	import com.ui.core.INewHelp;
	import com.ui.core.ScaleMode;
	import com.ui.core.UIComponent;
	import com.ui.data.PanelData;
	import com.ui.data.ScrollBarData;
	import com.ui.events.GScrollBarEvent;
	import com.ui.layout.GLayout;
	import com.ui.manager.UIManager;
	import com.ui.manager.ViewManage;
	import com.ui.skin.ASSkin;
	import com.ui.skin.SkinStyle;
	import com.utils.MathUtil;

	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	/**
	 * Game Panel
	 * 
	 * @author Cafe
	 * @version 20100801
	 */
	public class Panel extends UIComponent implements INewHelp
	{
		protected var _data:PanelData;
		protected var _bgSkin:DisplayObject;
		protected var _content:Sprite;
		protected var _modalSkin:Sprite;
		protected var _viewW:int;
		protected var _viewH:int;
		protected var _viewRect:Rectangle = new Rectangle();
		protected var _bounds:Rectangle = new Rectangle();
		public var _v_sb:ScrollBar;
		public var _h_sb:ScrollBar;
		protected var _menuTrigger:DisplayObject;
		protected var _closeButton:Button;
		protected var _helpNotice:DisplayObject;
		protected var _callLater:Function;

		override protected function create():void
		{
			_bgSkin = UIManager.getUI( _data.bgAsset );
			_content = new Sprite();
			_content.name = "content";
			_content.x = this._content.y = _data.padding;
			var className:String = _data.bgAsset.className;
			if (className != SkinStyle.emptySkin&&className != SkinStyle.modalSkin&&className != SkinStyle.panel_backgroundSkin)
				addChild( _bgSkin );
			addChild( _content );

			if (_data.modal) _modalSkin = ASSkin.modalSkin;
			switch(_data.scaleMode)
			{
				case ScaleMode.SCALE_WIDTH:
					_height = _bgSkin.height;
					break;
				case ScaleMode.SCALE_NONE:
					var offset:Point = UIManager.getOffset( _bgSkin );
					_width = _bgSkin.width + offset.x;
					_height = _bgSkin.height + offset.y;
					break;
			}
			addCloseButton();
		}

		protected function addvSb():void
		{
		}

		protected function addhSB():void
		{
		}

		override protected function layout():void
		{
			_bgSkin.width = _width;
			_bgSkin.height = _height;
			_viewW = Math.max( _base.minWidth, _width - _data.padding * 2 );
			_viewH = Math.max( _base.minHeight, _height - _data.padding * 2 );
			_viewRect.width = _viewW;
			_viewRect.height = _viewW;
			_content.scrollRect = _viewRect;
			if (_v_sb)
			{
				_v_sb.x = _width;
				if (_width == 0)
				{
					_v_sb.visible = false;
				}
				else
				{
					_v_sb.visible = true;
				}
				// - _data.padding - _v_sb.width;
				_v_sb.y = _data.padding;
			}
			if (_h_sb)
			{
				_h_sb.x = _data.padding;
				_h_sb.y = _height;
			}
			// - _data.padding - _h_sb.height;
			if (_closeButton)
			{
				_closeButton.x = _width - 26;
				_closeButton.y = 10;
			}
			reset();
		}

		protected function addCloseButton():void
		{
			if (_data.closeButtonData != null)
			{
				_data.closeButtonData.parent = this;
				_data.closeButtonData.height = _data.closeButtonData.width = 16;
				_closeButton = new Button( _data.closeButtonData );
				addChild( _closeButton );
				_closeButton.addEventListener( MouseEvent.CLICK, cloesButton_handler );
			}
		}

		private function cloesButton_handler( event:MouseEvent ):void
		{
			hide();
		}

		protected function reset():void
		{
			var data:ScrollBarData;
			resetBounds();
			var needV:Boolean = _bounds.height > _viewH;
			var needH:Boolean = _bounds.width > _viewW;

			// trace( _bounds.height,_viewH,name)
			if (needV && !needH)
			{
				// needH = _bounds.width > _viewW - _v_sb.width;
			}
			if (needH && !needV)
			{
				// needV = _bounds.height > _viewH - _h_sb.height;
			}
			var newW:int = _viewW;
			// - (needV ? _v_sb.width : 0);
			var newH:int = _viewH;
			// - (needH ? _h_sb.height : 0);
			if (_viewRect.width != newW || _viewRect.height != newH)
			{
				_viewRect.width = newW;
				_viewRect.height = newH;
				resizeContent();
				reset();
				return;
			}

			if (needV)
			{
				if (_v_sb == null)
				{
					data = _data.scrollBarData.clone();
					data.visible = false;
					data.direction = ScrollBarData.VERTICAL;
					_v_sb = new ScrollBar( data );
					_v_sb.x = _width;
					// _v_sb.y = _data.padding;
					addChild( _v_sb );
				}
				if (!_v_sb.visible)
				{
					_v_sb.visible = true;
					_v_sb.addEventListener( GScrollBarEvent.SCROLL, scrollHandler );
				}
				_v_sb.height = newH;
				_v_sb.resetValue( newH, 0, _bounds.height - newH, (_content.scrollRect ? _content.scrollRect.y : 0) );
			}
			else if (_v_sb && _v_sb.visible)
			{
				// _v_sb.removeEventListener( GScrollBarEvent.SCROLL, scrollHandler );
				_v_sb.visible = false;
				_viewRect.y = 0;
			}

			if (needH)
			{
				if (_h_sb == null)
				{
					data = _data.scrollBarData.clone();
					data.direction = ScrollBarData.HORIZONTAL;
					data.visible = false;
					_h_sb = new ScrollBar( data );
					addChild( _h_sb );
				}
				if (!_h_sb.visible)
				{
					_h_sb.visible = true;
					_h_sb.addEventListener( GScrollBarEvent.SCROLL, scrollHandler );
				}
				_h_sb.width = newW;
				_h_sb.resetValue( newW, 0, _bounds.width - newW, (_content.scrollRect ? +_content.scrollRect.x : 0) );
			}
			else if (_h_sb && _h_sb.visible)
			{
				// _h_sb.removeEventListener( GScrollBarEvent.SCROLL, scrollHandler );
				_h_sb.visible = false;
				_viewRect.x = 0;
			}

			_content.scrollRect = _viewRect;
		}

		protected function resizeContent():void
		{
		}

		protected function resetBounds():void
		{
			var total:int = _content.numChildren;
			var x:Number = 0;
			var y:Number = 0;
			var w:Number = _base.minWidth;
			var h:Number = _base.minHeight;
			for (var i:int = 0;i < total;i++)
			{
				var child:DisplayObject = _content.getChildAt( i );
				x = Math.min( x, child.x );
				y = Math.min( y, child.y );
				w = Math.max( w, child.x + child.width );
				h = Math.max( h, child.y + child.height );
			}
			_bounds = new Rectangle( x, y, w, h );
		}

		protected function scrollHandler( event:GScrollBarEvent ):void
		{
			if (event.direction == ScrollBarData.VERTICAL)
			{
				_viewRect.y = event.position;
			}
			else
			{
				_viewRect.x = event.position;
			}
			_content.scrollRect = _viewRect;
		}

		override protected function onShow():void
		{
			if (_data.modal)
			{
				UIManager.root.stage.focus = null;
				var topLeft:Point = parent.localToGlobal( MathUtil.ORIGIN );
				_modalSkin.x = -topLeft.x;
				_modalSkin.y = -topLeft.y;
				_modalSkin.width = UIManager.root.stage.stageWidth;
				_modalSkin.height = UIManager.root.stage.stageHeight;
				parent.addChildAt( _modalSkin, parent.numChildren - 1 );
				parent.swapChildrenAt( parent.getChildIndex( this ), parent.numChildren - 1 );
			}
			if (_v_sb || _h_sb)
				addEventListener( MouseEvent.MOUSE_WHEEL, mouseWheelHandler );
			if (_menuTrigger != null)
			{
				stage.addEventListener( MouseEvent.MOUSE_UP, stage_mouseUpHandler );
			}
			if (_data.isClickTop) ViewManage.add( this );
		}

		override protected function onHide():void
		{
			if (_data.modal && _modalSkin.parent)
			{
				_modalSkin.parent.removeChild( _modalSkin );
			}
			removeEventListener( MouseEvent.MOUSE_WHEEL, mouseWheelHandler );
			if (_menuTrigger != null)
			{
				stage.removeEventListener( MouseEvent.MOUSE_UP, stage_mouseUpHandler );
			}
			if (_data.isClickTop) ViewManage.remove( this );
		}

		protected function mouseWheelHandler( event:MouseEvent ):void
		{
			if (_v_sb && _v_sb.visible)
			{
				event.stopPropagation();
				_v_sb.scroll( event.delta * 2 );
			}
		}

		protected function stage_mouseUpHandler( event:MouseEvent ):void
		{
			var hitTarget:DisplayObject = UIManager.hitTest( UIManager.root.stage.mouseX, UIManager.root.stage.mouseY );
			if (!UIManager.atParent( hitTarget, this ))
			{
				var outside:Boolean = true;
				if (UIManager.atParent( hitTarget, _menuTrigger ))
				{
					outside = false;
				}
				if (outside)
				{
					hide();
				}
			}
		}

		public function Panel( data:PanelData )
		{
			_data = data;
			super( data );
		}

		public function add( value:DisplayObject ):void
		{
			if (!value) return;
			_content.addChild( value );
			if (value is UIComponent) GLayout.update( this, UIComponent( value ) );
			reset();
		}

		// 是否模态
		public function get modal():Boolean
		{
			return _data.modal;
		}

		public function resizeModal():void
		{
			if (_modalSkin == null) return;
			_modalSkin.width = UIManager.root.stage.stageWidth;
			_modalSkin.height = UIManager.root.stage.stageHeight;
		}

		public function get padding():int
		{
			return _data.padding;
		}

		public function set menuTrigger( value:DisplayObject ):void
		{
			_menuTrigger = value;
		}

		public function get content():Sprite
		{
			return _content;
		}

		public function get viewRect():Rectangle
		{
			return _viewRect;
		}

		public function scrollToBottom():void
		{
			if (_v_sb.visible == true)
			{
				_viewRect.y = _bounds.height - _viewH;
				_content.scrollRect = _viewRect;
			}
		}

		public function scrollSetHeightValue( value:uint ):void
		{
			if (_v_sb && _v_sb.visible)
				_v_sb.resetValue( _viewH, 0, _bounds.height - _viewH, value );
		}

		public function get viewH():int
		{
			return _viewH;
		}

		public function get viewbounds():Rectangle
		{
			return _bounds;
		}

		public function get helpNotice():DisplayObject
		{
			return _helpNotice;
		}

		public function set helpNotice( helpNotice:DisplayObject ):void
		{
			_helpNotice = helpNotice;
		}

		public function get callLater():Function
		{
			return _callLater;
		}

		public function set callLater( callLater:Function ):void
		{
			_callLater = callLater;
		}
	}
}
